#include "stdafx.h"
#include "str.h"
#include <stdio.h>
#include <wchar.h>
#include <stdarg.h>
#include <wtypes.h>
#include <stdlib.h>
#include <locale.h>

//using namespace Zen;
namespace Zen{ namespace utility{ 

	string ws2s(const wstring& ws)
	{
		std::string curLocale = setlocale(LC_ALL, "chs");        // curLocale = "C";
		//setlocale(LC_ALL, "chs");
		const wchar_t* _Source = ws.c_str();
		size_t _Dsize = 2 * ws.size() + 1;
		char *_Dest = new char[_Dsize];
		memset(_Dest,0,_Dsize);
		wcstombs(_Dest,_Source,_Dsize);
		std::string result = _Dest;
		delete []_Dest;
		setlocale(LC_ALL, curLocale.c_str());
		return result;
	}

	wstring s2ws(const string& s)
	{
		setlocale(LC_ALL, "chs"); 
		const char* _Source = s.c_str();
		size_t _Dsize = s.size() + 1;
		wchar_t *_Dest = new wchar_t[_Dsize];
		wmemset(_Dest, 0, _Dsize);
		mbstowcs(_Dest,_Source,_Dsize);
		std::wstring result = _Dest;
		delete []_Dest;
		setlocale(LC_ALL, "C");
		return result;
	}

	wchar_t* _char_to_wchar(const char* src, int src_len, int character_set, int& des_len)
	{
		if (src == NULL || 0 == src_len)
		{
			return NULL;
		}

		des_len = MultiByteToWideChar(character_set, 0, src, src_len, NULL, NULL );

		if (des_len == 0)
			return NULL;

		wchar_t* des = new wchar_t[des_len + 1];

		if (des == NULL)
			return NULL;

		if (0 == MultiByteToWideChar(character_set, 0, src, src_len, des, des_len))
		{
			delete [] des;
			return NULL;
		}

		des[des_len] = 0;

		return des;
	}

	char* _wchar_to_char(const wchar_t* src, int src_len, int character_set, int& des_len)
	{
		if (src == NULL || 0 == src_len)
		{
			return NULL;
		}

		if (src_len==-1)
		{
			src_len = (DWORD)wcslen(src);
		}

		des_len = WideCharToMultiByte(character_set, NULL, src, src_len, NULL, NULL, NULL, NULL);

		if(des_len==0)
		{
			return NULL;
		}

		char * des = new char[des_len + 1];
		memset(des, 0, des_len+1);

		if (des == NULL)
		{
			return NULL;
		}

		if(0 == WideCharToMultiByte(character_set, NULL, src, src_len, des, des_len,NULL,NULL))
		{
			delete [] des;
			return NULL;
		}

		des[des_len] = 0;
		return	des;
	}

	wchar_t* _char_to_wchar(const char* src, int src_len, int character_set)
	{
		if (src == NULL)
		{
			return NULL;
		}

		int des_len = MultiByteToWideChar(character_set, 0, src, src_len, NULL, NULL );

		if (des_len == 0)
			return NULL;

		wchar_t* des = new wchar_t[des_len + 1];

		if (des == NULL)
			return NULL;

		if (0 == MultiByteToWideChar(character_set, 0, src, src_len, des, des_len))
		{
			delete [] des;
			return NULL;
		}

		des[des_len] = 0;

		return des;
	}

	char* _wchar_to_char(const wchar_t* src, int src_len, int character_set)
	{
		if (src == NULL)
		{
			return NULL;
		}

		if (src_len==-1)
		{
			src_len = (DWORD)wcslen(src);
		}

		int des_len = WideCharToMultiByte(character_set, NULL, src, src_len, NULL, NULL, NULL, NULL);

		if(des_len==0)
		{
			return NULL;
		}

		char * des = new char[des_len + 1];
		memset(des, 0, des_len+1);

		if (des == NULL)
		{
			return NULL;
		}

		if(0 == WideCharToMultiByte(character_set, NULL, src, src_len, des, des_len,NULL,NULL))
		{
			delete [] des;
			return NULL;
		}

		des[des_len] = 0;
		return	des;
	}

	std::wstring string_to_wstring(const std::string& src, int character_set)
	{
		int des_len = 0;
		wchar_t* des = _char_to_wchar(src.c_str(), src.length(), character_set, des_len);
		std::wstring des_string(des, des_len);
		delete []des;
		return des_string;
	}

	std::string wstring_to_string(const std::wstring& src, int character_set)
	{
		int des_len = 0;
		char* des = _wchar_to_char(src.c_str(), src.length(), character_set, des_len);
		std::string des_string(des, des_len);
		delete []des;
		return des_string;
	}

	std::string conver_string( const std::string& src, int character_set_src, int character_set_des)
	{
		std::wstring des = string_to_wstring(src, character_set_src);
		return wstring_to_string(des, character_set_des);
	}

	string& replace_all(string& str, const string& old_value, const string& new_value)
	{   
		while(true)
		{
			string::size_type pos(0);
			if ((pos = str.find(old_value)) != string::npos)
				str.replace(pos, old_value.length(), new_value);
			else
				break;
		}
		return str;
	}

	string& replace_all_distinct(string& str, const string& old_value, const string& new_value)
	{
		for(string::size_type pos(0); pos != string::npos; pos += new_value.length() )
		{
			if ((pos = str.find(old_value,pos)) != string::npos)
				str.replace(pos,old_value.length(),new_value);
			else
				break;
		}
		return str;
	}

	int seperate_string( IN char* buf, int size, string_vector& strings, char delimit )
	{
		if (buf == NULL || size == 0)
			return -1;

		char* tmp = buf;

		int count = 0;

		string str;

		while (count != size)
		{
			if (buf[count] == delimit)
			{
				strings.push_back(str);
				str.clear();
			}
			else
				str.push_back(buf[count]);

			count ++;
		}

		if (size && count == size && buf[count] != delimit)
		{
			strings.push_back(str);
		}

		return 0;
	}

	int seperate_string( const string& src, string_vector& strings, char delimit )
	{
		return (seperate_string((char*)src.c_str(), src.length(), strings, delimit));
	}

}}

